package com.kuaiyin.service.impl;

import com.aliyuncs.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kuaiyin.dto.LoginDTO;
import com.kuaiyin.dto.UserDTO;
import com.kuaiyin.entity.User;
import com.kuaiyin.enums.BizCodeEnum;
import com.kuaiyin.enums.Status;
import com.kuaiyin.exception.BaseException;
import com.kuaiyin.mapper.UserMapper;
import com.kuaiyin.service.IUserService;
import com.kuaiyin.utils.JwtUtils;
import com.kuaiyin.utils.PageHelper;
import com.kuaiyin.utils.PageResult;
import com.kuaiyin.utils.RedisUtils;
import com.kuaiyin.vo.LoginVO;
import com.kuaiyin.vo.UserDetailVO;
import com.kuaiyin.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * <p>
 * 用户基础信息表（使用逻辑外键） 服务实现类
 * </p>
 *
 * @author ng
 * @since 2025-04-21
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisUtils redisUtils;


    @Override
    public UserDetailVO getById(Long id) {
//        1、查询用户信息
        User user = super.getById(id);
        if (user == null) {
            throw BaseException.of(BizCodeEnum.LOGIN_USER_NOT_EXIST);
        }
//2、获取部门信息
        UserDetailVO UserdetailVO = new UserDetailVO(); //将user对象拷贝到userVO对象中
        Integer departmentId = user.getDepartmentId();   //获取部门ID
        if (departmentId != null) {
            String departmentName = super.getBaseMapper().getDepartmentById(departmentId); //根据部门ID查询部门名称
            UserdetailVO.setDepartmentName(departmentName); //设置部门名称
        }
        BeanUtils.copyProperties(user, UserdetailVO);
        // 3. 手动设置额外字段
        UserdetailVO.setEmail(user.getEmail());
        UserdetailVO.setPhone(user.getPhone());
        UserdetailVO.setPassword("******");
        System.out.println("UserdetailVO{}" + UserdetailVO);
        return UserdetailVO;
    }

    @Override
    public void saveUser(UserDTO userDTO) {
        // 非空校验前置，避免无效数据库查询
        if (StringUtils.isEmpty(userDTO.getEmail())) {
            throw BaseException.of(BizCodeEnum.USER_REGISTER_EMAIL_EMPTY);
        }
        if (StringUtils.isEmpty(userDTO.getUsername())) {
            throw BaseException.of(BizCodeEnum.USER_REGISTER_USERNAME_EMPTY);
        }
        if (StringUtils.isEmpty(userDTO.getPassword())) {
            throw BaseException.of(BizCodeEnum.USER_REGISTER_PASSWORD_EMPTY);
        }
        if (StringUtils.isEmpty(userDTO.getPhone())) {
            throw BaseException.of(BizCodeEnum.USER_REGISTER_PHONE_EMPTY);
        }
        if (userDTO.getDepartmentId() == null || userDTO.getDepartmentId() <= 0) {
            throw BaseException.of(BizCodeEnum.USER_REGISTER_DEPARTMENT_EMPTY);
        }

        // 唯一性校验
        Integer userByUsername = userMapper.getUserByUsername(userDTO.getUsername());
        Integer countPhone = userMapper.getUserByPhone(userDTO.getPhone());
        Integer countEmail = userMapper.getUserByEmail(userDTO.getEmail());

        if (userByUsername > 0) {
            throw BaseException.of(BizCodeEnum.USER_REGISTER_USERNAME_EXISTS);
        }
        if (countPhone > 0) {
            throw BaseException.of(BizCodeEnum.USER_REGISTER_PHONE_EXISTS);
        }
        if (countEmail > 0) {
            throw BaseException.of(BizCodeEnum.USER_REGISTER_EMAIL_EXISTS);
        }

        // 属性拷贝
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        user.setStatus(Status.fromCode(userDTO.getStatus()));  //状态转换
        user.setPassword(DigestUtils.md5DigestAsHex(userDTO.getPassword().getBytes()));  //密码加密
        userMapper.insert(user);
    }


    @Override
    public void updateUserStatus(Long id, Integer status) {
        User user = new User();
        user.setId(id);
        user.setStatus(Status.fromCode(status));
        userMapper.updateById(user);
    }

    @Override
    public PageResult<UserVO> getUserPage(Integer page, Integer size, Consumer<LambdaQueryWrapper<User>> condition) {
        return PageHelper.queryWithVo(page, size, userMapper, UserVO.class, condition);
    }

    @Override
    public void updateUser(Long id, UserDTO userDTO) {
        userDTO.setId(id);
        //校验名称是否存在
        if (lambdaQuery().eq(User::getUsername, userDTO.getUsername()).ne(User::getId, id).exists()) {
            throw BaseException.of(BizCodeEnum.LOGIN_USER_EXISTS);
        }
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        user.setPassword(DigestUtils.md5DigestAsHex(userDTO.getPassword().getBytes()));
        userMapper.updateById(user);
    }

    @Override
    public List<UserVO> getUserList() {
        return userMapper.selectAllWithDept();
    }

    @Override
    public LoginVO login(LoginDTO loginDTO) {
        String key = "captcha:" + loginDTO.getUuid();
        String captchaCode = loginDTO.getCaptcha();   //验证码
        String storedCode = (String) redisUtils.get(key);
        // 根据用户名查询用户信息
        User user = userMapper.selectOne(new QueryWrapper<User>().eq("username", loginDTO.getUsername()));
        if (user == null) {
            // 如果用户不存在，抛出异常
            throw BaseException.of(BizCodeEnum.LOGIN_USERNAME_OR_PASSWORD_ERROR);
        }
        if (StringUtils.isEmpty(loginDTO.getUsername())) {
            // 如果用户名为空，抛出异常
            throw BaseException.of(BizCodeEnum.LOGIN_USERNAME_EMPTY);
        }
        if (StringUtils.isEmpty(loginDTO.getPassword())) {
            // 如果密码为空，抛出异常
            throw BaseException.of(BizCodeEnum.LOGIN_PASSWORD_EMPTY);
        }
        // 验证用户输入的密码与数据库中存储的密码是否一致
        if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(loginDTO.getPassword().getBytes()))) {
            // 如果密码不一致，抛出异常
            throw BaseException.of(BizCodeEnum.LOGIN_USERNAME_OR_PASSWORD_ERROR);
        }
        if (user.getStatus() == Status.NORMAL) {
            // 如果用户状态为冻结，抛出异常
            throw BaseException.of(BizCodeEnum.LOGIN_USER_FROZEN);
        }
        if (storedCode == null) {
            // 验证码不存在
            throw BaseException.of(BizCodeEnum.LOGIN_CAPTCHA_EXPIRED);
        }
        if (!storedCode.equalsIgnoreCase(captchaCode)) {
            // 验证码不匹配
            throw BaseException.of(BizCodeEnum.LOGIN_CAPTCHA_MISMATCH);
        }
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getUsername());
        String jwt = JwtUtils.generateJwt(claims);
        // 将User对象转换为UserVO对象
        LoginVO loginVO = new LoginVO(user.getId(), user.getUsername(), jwt);
        BeanUtils.copyProperties(user, loginVO);
        log.info("{}--------登录成功", loginDTO.getUsername());
        return loginVO;
    }


}
